#ifndef IMAGE_PREPROCESSOR_H_
#define IMAGE_PREPROCESSOR_H_
#include <memory>

#include "common/basic_type.h"

struct ImagePreProcessParameters {
  ///@brief pixel scale
  float pixel_scale;
  /// @brief resize scale
  float resize_scale;
  /// @brief roi
  Rect crop_area;
  /// @brief norm mean
  std::vector<float> norm_mean;
  /// @brief norm standard
  std::vector<float> norm_std;
};

/// @brief crop, resize, norm, image for deep learning in cpu
/// @param image source image
/// @param parameters parameters
/// @param dev_addr device(gpu) address
/// @param err error message
/// @return if no error return true, otherwise false
bool resize_norm_chw_cpu(cv::Mat const& image,
                         ImagePreProcessParameters const& parameters,
                         void* const dev_addr, std::string& err) noexcept;

bool resize_norm_chw_cpu_bgr(cv::Mat const& image, std::string const& name,
                             ImagePreProcessParameters const& parameters,
                             float* out, std::string& err) noexcept;

class ResizeNormCHWNPP {
 public:
  ResizeNormCHWNPP() noexcept;
  ~ResizeNormCHWNPP();
  ResizeNormCHWNPP(ResizeNormCHWNPP const&) = delete;
  ResizeNormCHWNPP& operator=(ResizeNormCHWNPP const&) = delete;
  ResizeNormCHWNPP(ResizeNormCHWNPP&&) = delete;
  ResizeNormCHWNPP& operator=(ResizeNormCHWNPP&&) = delete;

  /// @brief crop, resize, norm, image for deep learning in cuda gpu
  /// @param image source image
  /// @param parameters parameters
  /// @param dev_addr device(gpu) address
  /// @param err error message
  /// @return if no error return true, otherwise false
  bool operator()(cv::Mat const& image,
                  ImagePreProcessParameters const& parameters,
                  void* const dev_addr, std::string& err) noexcept;

 private:
  /// @brief image raw data in gpu, uchar
  std::shared_ptr<void> gpu_img_buf_ptr_;
  /// @brief gpu_img_buf_size
  unsigned long gpu_img_buf_size_;

  /// @brief image resize data in gpu, uchar
  std::shared_ptr<void> gpu_resize_img_buf_ptr_;
  /// @brief gpu resize image buf size
  unsigned long gpu_resize_img_buf_size_;

  /// @brief image crop data in gpu,uchar
  std::shared_ptr<void> gpu_crop_img_buf_ptr_;
  /// @brief gpu crop image buf size
  unsigned long gpu_crop_img_buf_size_;

  /// @brief image norm data in gpu, float
  std::shared_ptr<void> gpu_data_buf_ptr_;
  unsigned long gpu_data_buf_size_;
};

#endif  // !IMAGE_PREPROCESSOR_H_
